package com.haixiaoke.flat.workOrder.controller;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.haixiaoke.auth.AuthCheck;
import com.haixiaoke.saas.common.annotation.RepeatSubmit;
import com.haixiaoke.saas.common.config.WeChatConfig;
import com.haixiaoke.saas.common.constant.WorkOrderConstants;
import com.haixiaoke.saas.common.core.domain.AjaxResult;
import com.haixiaoke.saas.common.core.page.TableDataInfo;
import com.haixiaoke.saas.common.core.redis.RedisCache;
import com.haixiaoke.saas.common.exception.ServiceException;
import com.haixiaoke.saas.common.weChat.domain.UnifiedOrder;
import com.haixiaoke.saas.common.weChat.service.WeChatService;
import com.haixiaoke.saas.department.domain.WechatAccount;
import com.haixiaoke.saas.department.service.IWechatAccountService;
import com.haixiaoke.saas.house.domain.House;
import com.haixiaoke.saas.house.service.IHouseService;
import com.haixiaoke.saas.system.BaseController;
import com.haixiaoke.saas.user.domain.UserConsumer;
import com.haixiaoke.saas.user.service.IUserConsumerService;
import com.haixiaoke.saas.workOrder.domain.WorkOrder;
import com.haixiaoke.saas.workOrder.domain.WorkOrderRecord;
import com.haixiaoke.saas.workOrder.service.IWorkOrderRecordService;
import com.haixiaoke.saas.workOrder.service.IWorkOrderService;
import com.haixiaoke.token.FrontTokenComponent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 工单Controller
 *
 * @author qixi
 * @date 2024-09-09
 */
@RestController
@RequestMapping("/front/flat/workOrder/workOrder")
public class FlatWorkOrderController extends BaseController {
    @Autowired
    private IWorkOrderService workOrderService;
    @Autowired
    private IWechatAccountService wechatAccountService;
    @Autowired
    private IUserConsumerService userConsumerService;
    @Autowired
    private FrontTokenComponent frontTokenComponent;
    @Autowired
    private WeChatConfig weChatConfig;
    @Autowired
    private WeChatService weChatService;
    @Autowired
    private IHouseService houseService;
    @Autowired
    private IWorkOrderRecordService workOrderRecordService;
    @Autowired
    private RedisCache redisCache;

    /**
     * 查询工单列表
     */
    @GetMapping("/list")
    public TableDataInfo list(WorkOrder workOrder) {
        startPage();
        workOrder.setConUserId(frontTokenComponent.getUserIdNotNull());
        List<WorkOrder> list = workOrderService.flatSelectWorkOrderList(workOrder);
        return getDataTable(list);
    }

    /**
     * 获取工单详细信息
     */
    @GetMapping(value = "/{workOrderId}")
    public AjaxResult getInfo(@PathVariable("workOrderId") String workOrderId) {
        return success(workOrderService.flatSelectWorkOrderByWorkOrderId(workOrderId));
    }

    /**
     * 查询工单跟进记录列表
     */
    @GetMapping("/record/list")
    // @AuthCheck
    public AjaxResult list(WorkOrderRecord workOrderRecord) {
        String workOrderId = workOrderRecord.getWorkOrderId();
        if (StrUtil.isBlank(workOrderId)) {
            throw new ServiceException("工单ID不能为空");
        }
        List<WorkOrderRecord> list = workOrderRecordService.selectWorkOrderRecordByRecordType(workOrderId, WorkOrderConstants.RECORD_TYPE_USER_VISIBLE);
        return success(list);
    }


    /**
     * 新增工单
     */
    @AuthCheck
    @PostMapping
    @RepeatSubmit
    public AjaxResult add(@RequestBody WorkOrder workOrder) {
        House house = houseService.selectHouseById(workOrder.getHouseId());
        workOrder.setTenantId(house.getTenantId());
        workOrder.setCreateBy(frontTokenComponent.getLoginUser().getUser().getUserName());
        workOrder.setWorkOrderSource(WorkOrderConstants.WORK_ORDER_SOURCE_C_APPLET);
        workOrder.setPremisesAddress(house.getPremisesAddress());
        return workOrderService.insertWorkOrder(workOrder, frontTokenComponent.getLoginUser().getUser().getUserMobile());
    }

    /**
     * 编辑工单
     */
    @AuthCheck
    @PutMapping
    @RepeatSubmit
    public AjaxResult edit(@RequestBody WorkOrder workOrder) {
        workOrder.setUpdateBy(frontTokenComponent.getLoginUser().getUser().getUserName());
        workOrder.setOperatorId(frontTokenComponent.getLoginUser().getUser().getUserId());
        return toAjax(workOrderService.flatUpdateWorkOrder(workOrder, frontTokenComponent.getLoginUser().getUser().getUserMobile()));
    }

    /**
     * 取消预约
     */
    @AuthCheck
    @PutMapping("/reject")
    @RepeatSubmit
    public AjaxResult rejectWorkOrder(@RequestBody WorkOrderRecord workOrderRecord) {
        return workOrderService.rejectWorkOrder(workOrderRecord, null,
                StrUtil.isBlank(frontTokenComponent.getLoginUser().getUser().getUserName()) ? frontTokenComponent.getLoginUser().getUser().getUserMobile() :
                        frontTokenComponent.getLoginUser().getUser().getUserName());
    }

    /**
     * 工单支付
     */
    @AuthCheck
    @RepeatSubmit
    @GetMapping("/unifiedPay/{workOrderId}/{payType}")
    public AjaxResult pay(@PathVariable("workOrderId") String workOrderId, @PathVariable("payType") String payType) {
        WorkOrder order = workOrderService.selectWorkOrderByWorkOrderId(workOrderId);
        if (ObjectUtil.isEmpty(order)) {
            return error("订单数据异常");
        }
        // 只有待支付订单
        if (!WorkOrderConstants.WORK_ORDER_STATE_WAIT_PAY.equals(order.getWorkOrderState())) {
            return error("订单状态有误无法支付");
        }
        UserConsumer userConsumer = userConsumerService.selectUserConsumerByUserId(frontTokenComponent.getUserIdNotNull());
        if (ObjectUtil.isEmpty(userConsumer) || StrUtil.isBlank(userConsumer.getOpenId())) {
            return error("用户数据异常");
        }
        WechatAccount account = wechatAccountService.selectWechatAccountByTenantId(order.getTenantId());
        if (ObjectUtil.isEmpty(account)) {
            return error("商家信息错误，请联系管理员");
        }

        UnifiedOrder unifiedOrder = getUnifiedOrder(account, order);
        unifiedOrder.setOpenId(userConsumer.getOpenId());
        if (WorkOrderConstants.WORK_ORDER_PAYMENT_TYPE_WECHAT.equals(payType)) {
            return weChatService.unifiedOrder(unifiedOrder);
        }else {
            String url = redisCache.getCacheObject(WorkOrderConstants.WORK_ORDER_NATIVE_PAY_REDIS_KEY + workOrderId);
            if (StrUtil.isBlank(url)){
                AjaxResult ajaxResult = weChatService.nativeOrder(unifiedOrder);
                url = StrUtil.toString(ajaxResult.get("data"));
                redisCache.setCacheObject(WorkOrderConstants.WORK_ORDER_NATIVE_PAY_REDIS_KEY + workOrderId, url, 120, TimeUnit.MINUTES);
            }
            return AjaxResult.success("success", url);
        }
    }

    /**
     * 删除工单
     */
    @DeleteMapping("/{workOrderId}")
    public AjaxResult remove(@PathVariable("workOrderId") String workOrderId) {
        return toAjax(workOrderService.softDeleteWorkOrderByWorkOrderId(workOrderId));
    }

    private UnifiedOrder getUnifiedOrder(WechatAccount account, WorkOrder order) {
        UnifiedOrder unifiedOrder = new UnifiedOrder();
        unifiedOrder.setAppId(weChatConfig.getAppId());
        unifiedOrder.setAccountId(account.getAccountId());
        unifiedOrder.setAccountApiKey(account.getAccountApiKey());
        unifiedOrder.setAttach(account.getTenantId());
        unifiedOrder.setOutTradeNo(order.getWorkOrderId());
        BigDecimal totalFee = order.getWorkOrderAmount();
        unifiedOrder.setCallBackUrl(weChatConfig.getWorkOrderUnifiedPayCallBackUrl());
        unifiedOrder.setBody("房屋管家-工单小程序支付");

        // TODO: 2024/4/22 金额写死
        unifiedOrder.setTotalFee(/*totalFee.multiply(BigDecimal.valueOf(100)).intValue()*/1);
        return unifiedOrder;
    }

}
